#include "iap.h"

u16 iapbuf[1024] = {0}; //用于缓存数据的数组
u16 receiveDataCur = 0;	//当前iapbuffer中已经填充的数据长度,一次填充满了之后写入flash并清零

typedef  void (*iapfun)(void);				//定义一个函数类型的参数.
iapfun jump2app;

//设置栈顶地址
//addr:栈顶地址
__asm void MSR_MSP(u32 addr) 
{
    MSR MSP, r0 			//set Main Stack value
    BX r14
}

//跳转到应用程序段
//appxaddr:用户代码起始地址.
/*void iap_load_app(u32 appxaddr)
{
	if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)	//检查栈顶地址是否合法.0x20000000是sram的起始地址,也是程序的栈顶地址
	{ 
		//printf("ok\r\n");
		Delay_Ms(10);
		jump2app=(iapfun)*(vu32*)(appxaddr+4);		//用户代码区第二个字为程序开始地址(复位地址)		
		MSR_MSP(*(vu32*)appxaddr);					//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
		jump2app();									//跳转到APP.
	}
	else
	{
		//printf("program in flash is error\r\n");
	}
}*/

//*************************************************************************************************
// 函数名称:  iap_load_app
// 函数功能:  跳转到应用程序段
// 输入参数:  
// 	appxaddr		-	用户代码起始地址
// 返回值:  无
//**************************************************************************************************
/*void iap_load_app(uint32_t appxaddr)
{
    uint32_t JumpAddress;
	iapfun jump2app;

    // 先把系统时钟中断关闭，不然程序会跑飞
    SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;

    JumpAddress = *(__IO uint32_t*) (appxaddr + 4);
    jump2app = (iapfun) JumpAddress;
    __set_MSP(*(__IO uint32_t*) appxaddr);
    jump2app();
	
#if 0 
	
		// 先把系统时钟中断关闭，不然程序会跑飞
		SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;  
		
		if( ((*(volatile uint32_t *)appxaddr)&0x2FFE0000)==0x20000000 )	// 检查栈顶地址是否合法.
		{ 
			jump2app=(iapfun)*(volatile uint32_t *)(appxaddr+4);		      // 用户代码区第二个字为程序开始地址(复位地址)		
			__set_MSP( *(volatile uint32_t *)appxaddr );					        // 初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
			jump2app();									                                  // 跳转到APP.
		}
		
#endif 

}*/


//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(u32 appxaddr)
{
    // 先把系统时钟中断关闭，不然程序会跑飞
	SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;  
	
	if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)	//检查栈顶地址是否合法.0x20000000是sram的起始地址,也是程序的栈顶地址
	{ 
		//printf("ok\r\n");
		Delay_Ms(10);
		jump2app=(iapfun)*(vu32*)(appxaddr+4);		//用户代码区第二个字为程序开始地址(复位地址)		
		MSR_MSP(*(vu32*)appxaddr);					//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
		jump2app();									//跳转到APP.
	}
	else
	{
		//printf("program in flash is error\r\n");
	}
}















